home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / textwrap.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  11KB  |  297 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Text wrapping and filling.
  5. '''
  6. __revision__ = '$Id: textwrap.py,v 1.35.4.3 2005/09/15 17:21:59 rhettinger Exp $'
  7. import string
  8. import re
  9.  
  10. try:
  11.     (True, False)
  12. except NameError:
  13.     (True, False) = (1, 0)
  14.  
  15. __all__ = [
  16.     'TextWrapper',
  17.     'wrap',
  18.     'fill']
  19. _whitespace = '\t\n\x0b\x0c\r '
  20.  
  21. class TextWrapper:
  22.     '''
  23.     Object for wrapping/filling text.  The public interface consists of
  24.     the wrap() and fill() methods; the other methods are just there for
  25.     subclasses to override in order to tweak the default behaviour.
  26.     If you want to completely replace the main wrapping algorithm,
  27.     you\'ll probably have to override _wrap_chunks().
  28.  
  29.     Several instance attributes control various aspects of wrapping:
  30.       width (default: 70)
  31.         the maximum width of wrapped lines (unless break_long_words
  32.         is false)
  33.       initial_indent (default: "")
  34.         string that will be prepended to the first line of wrapped
  35.         output.  Counts towards the line\'s width.
  36.       subsequent_indent (default: "")
  37.         string that will be prepended to all lines save the first
  38.         of wrapped output; also counts towards each line\'s width.
  39.       expand_tabs (default: true)
  40.         Expand tabs in input text to spaces before further processing.
  41.         Each tab will become 1 .. 8 spaces, depending on its position in
  42.         its line.  If false, each tab is treated as a single character.
  43.       replace_whitespace (default: true)
  44.         Replace all whitespace characters in the input text by spaces
  45.         after tab expansion.  Note that if expand_tabs is false and
  46.         replace_whitespace is true, every tab will be converted to a
  47.         single space!
  48.       fix_sentence_endings (default: false)
  49.         Ensure that sentence-ending punctuation is always followed
  50.         by two spaces.  Off by default because the algorithm is
  51.         (unavoidably) imperfect.
  52.       break_long_words (default: true)
  53.         Break words longer than \'width\'.  If false, those words will not
  54.         be broken, and some lines might be longer than \'width\'.
  55.     '''
  56.     whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace))
  57.     unicode_whitespace_trans = { }
  58.     uspace = ord(u' ')
  59.     for x in map(ord, _whitespace):
  60.         unicode_whitespace_trans[x] = uspace
  61.     
  62.     wordsep_re = re.compile('(\\s+|[^\\s\\w]*\\w+[a-zA-Z]-(?=\\w+[a-zA-Z])|(?<=[\\w\\!\\"\\\'\\&\\.\\,\\?])-{2,}(?=\\w))')
  63.     sentence_end_re = re.compile('[%s][\\.\\!\\?][\\"\\\']?' % string.lowercase)
  64.     
  65.     def __init__(self, width = 70, initial_indent = '', subsequent_indent = '', expand_tabs = True, replace_whitespace = True, fix_sentence_endings = False, break_long_words = True):
  66.         self.width = width
  67.         self.initial_indent = initial_indent
  68.         self.subsequent_indent = subsequent_indent
  69.         self.expand_tabs = expand_tabs
  70.         self.replace_whitespace = replace_whitespace
  71.         self.fix_sentence_endings = fix_sentence_endings
  72.         self.break_long_words = break_long_words
  73.  
  74.     
  75.     def _munge_whitespace(self, text):
  76.         '''_munge_whitespace(text : string) -> string
  77.  
  78.         Munge whitespace in text: expand tabs and convert all other
  79.         whitespace characters to spaces.  Eg. " foo\tbar
  80.  
  81. baz"
  82.         becomes " foo    bar  baz".
  83.         '''
  84.         if self.expand_tabs:
  85.             text = text.expandtabs()
  86.         
  87.         if self.replace_whitespace:
  88.             if isinstance(text, str):
  89.                 text = text.translate(self.whitespace_trans)
  90.             elif isinstance(text, unicode):
  91.                 text = text.translate(self.unicode_whitespace_trans)
  92.             
  93.         
  94.         return text
  95.  
  96.     
  97.     def _split(self, text):
  98.         """_split(text : string) -> [string]
  99.  
  100.         Split the text to wrap into indivisible chunks.  Chunks are
  101.         not quite the same as words; see wrap_chunks() for full
  102.         details.  As an example, the text
  103.           Look, goof-ball -- use the -b option!
  104.         breaks into the following chunks:
  105.           'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
  106.           'use', ' ', 'the', ' ', '-b', ' ', 'option!'
  107.         """
  108.         chunks = self.wordsep_re.split(text)
  109.         chunks = filter(None, chunks)
  110.         return chunks
  111.  
  112.     
  113.     def _fix_sentence_endings(self, chunks):
  114.         '''_fix_sentence_endings(chunks : [string])
  115.  
  116.         Correct for sentence endings buried in \'chunks\'.  Eg. when the
  117.         original text contains "... foo.
  118. Bar ...", munge_whitespace()
  119.         and split() will convert that to [..., "foo.", " ", "Bar", ...]
  120.         which has one too few spaces; this method simply changes the one
  121.         space to two.
  122.         '''
  123.         i = 0
  124.         pat = self.sentence_end_re
  125.         while i < len(chunks) - 1:
  126.             if chunks[i + 1] == ' ' and pat.search(chunks[i]):
  127.                 chunks[i + 1] = '  '
  128.                 i += 2
  129.                 continue
  130.             i += 1
  131.  
  132.     
  133.     def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
  134.         '''_handle_long_word(chunks : [string],
  135.                              cur_line : [string],
  136.                              cur_len : int, width : int)
  137.  
  138.         Handle a chunk of text (most likely a word, not whitespace) that
  139.         is too long to fit in any line.
  140.         '''
  141.         space_left = max(width - cur_len, 1)
  142.         if self.break_long_words:
  143.             cur_line.append(reversed_chunks[-1][:space_left])
  144.             reversed_chunks[-1] = reversed_chunks[-1][space_left:]
  145.         elif not cur_line:
  146.             cur_line.append(reversed_chunks.pop())
  147.         
  148.  
  149.     
  150.     def _wrap_chunks(self, chunks):
  151.         '''_wrap_chunks(chunks : [string]) -> [string]
  152.  
  153.         Wrap a sequence of text chunks and return a list of lines of
  154.         length \'self.width\' or less.  (If \'break_long_words\' is false,
  155.         some lines may be longer than this.)  Chunks correspond roughly
  156.         to words and the whitespace between them: each chunk is
  157.         indivisible (modulo \'break_long_words\'), but a line break can
  158.         come between any two chunks.  Chunks should not have internal
  159.         whitespace; ie. a chunk is either all whitespace or a "word".
  160.         Whitespace chunks will be removed from the beginning and end of
  161.         lines, but apart from that whitespace is preserved.
  162.         '''
  163.         lines = []
  164.         if self.width <= 0:
  165.             raise ValueError('invalid width %r (must be > 0)' % self.width)
  166.         
  167.         chunks.reverse()
  168.         while chunks:
  169.             cur_line = []
  170.             cur_len = 0
  171.             if lines:
  172.                 indent = self.subsequent_indent
  173.             else:
  174.                 indent = self.initial_indent
  175.             width = self.width - len(indent)
  176.             if chunks[-1].strip() == '' and lines:
  177.                 del chunks[-1]
  178.             
  179.             while chunks:
  180.                 l = len(chunks[-1])
  181.                 if cur_len + l <= width:
  182.                     cur_line.append(chunks.pop())
  183.                     cur_len += l
  184.                     continue
  185.                 break
  186.             if chunks and len(chunks[-1]) > width:
  187.                 self._handle_long_word(chunks, cur_line, cur_len, width)
  188.             
  189.             if cur_line and cur_line[-1].strip() == '':
  190.                 del cur_line[-1]
  191.             
  192.             if cur_line:
  193.                 lines.append(indent + ''.join(cur_line))
  194.                 continue
  195.         return lines
  196.  
  197.     
  198.     def wrap(self, text):
  199.         """wrap(text : string) -> [string]
  200.  
  201.         Reformat the single paragraph in 'text' so it fits in lines of
  202.         no more than 'self.width' columns, and return a list of wrapped
  203.         lines.  Tabs in 'text' are expanded with string.expandtabs(),
  204.         and all other whitespace characters (including newline) are
  205.         converted to space.
  206.         """
  207.         text = self._munge_whitespace(text)
  208.         chunks = self._split(text)
  209.         if self.fix_sentence_endings:
  210.             self._fix_sentence_endings(chunks)
  211.         
  212.         return self._wrap_chunks(chunks)
  213.  
  214.     
  215.     def fill(self, text):
  216.         """fill(text : string) -> string
  217.  
  218.         Reformat the single paragraph in 'text' to fit in lines of no
  219.         more than 'self.width' columns, and return a new string
  220.         containing the entire wrapped paragraph.
  221.         """
  222.         return '\n'.join(self.wrap(text))
  223.  
  224.  
  225.  
  226. def wrap(text, width = 70, **kwargs):
  227.     """Wrap a single paragraph of text, returning a list of wrapped lines.
  228.  
  229.     Reformat the single paragraph in 'text' so it fits in lines of no
  230.     more than 'width' columns, and return a list of wrapped lines.  By
  231.     default, tabs in 'text' are expanded with string.expandtabs(), and
  232.     all other whitespace characters (including newline) are converted to
  233.     space.  See TextWrapper class for available keyword args to customize
  234.     wrapping behaviour.
  235.     """
  236.     w = TextWrapper(width = width, **kwargs)
  237.     return w.wrap(text)
  238.  
  239.  
  240. def fill(text, width = 70, **kwargs):
  241.     """Fill a single paragraph of text, returning a new string.
  242.  
  243.     Reformat the single paragraph in 'text' to fit in lines of no more
  244.     than 'width' columns, and return a new string containing the entire
  245.     wrapped paragraph.  As with wrap(), tabs are expanded and other
  246.     whitespace characters converted to space.  See TextWrapper class for
  247.     available keyword args to customize wrapping behaviour.
  248.     """
  249.     w = TextWrapper(width = width, **kwargs)
  250.     return w.fill(text)
  251.  
  252.  
  253. def dedent(text):
  254.     """dedent(text : string) -> string
  255.  
  256.     Remove any whitespace than can be uniformly removed from the left
  257.     of every line in `text`.
  258.  
  259.     This can be used e.g. to make triple-quoted strings line up with
  260.     the left edge of screen/whatever, while still presenting it in the
  261.     source code in indented form.
  262.  
  263.     For example:
  264.  
  265.         def test():
  266.             # end first line with \\ to avoid the empty line!
  267.             s = '''            hello
  268.               world
  269.             '''
  270.             print repr(s)          # prints '    hello
  271.       world
  272.     '
  273.             print repr(dedent(s))  # prints 'hello
  274.   world
  275. '
  276.     """
  277.     lines = text.expandtabs().split('\n')
  278.     margin = None
  279.     for line in lines:
  280.         content = line.lstrip()
  281.         if not content:
  282.             continue
  283.         
  284.         indent = len(line) - len(content)
  285.         if margin is None:
  286.             margin = indent
  287.             continue
  288.         margin = min(margin, indent)
  289.     
  290.     if margin is not None and margin > 0:
  291.         for i in range(len(lines)):
  292.             lines[i] = lines[i][margin:]
  293.         
  294.     
  295.     return '\n'.join(lines)
  296.  
  297.